/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package taskmanager2ndedition.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import taskmanager2ndedition.Connection;

/**
 *
 * @author Александр
 */

public class ServerConnection implements Connection, Runnable{

    private Socket socket;    
    private ObjectInputStream in;    
    private ObjectOutputStream out;    
    private boolean established;    
    private CmdInterpretator cmdInterpreter;
    private static int timeout;
    private Server server;
    private boolean loggedIn = false;
    private int sessionId;
    
    public static void Init(int timeout){
        ServerConnection.timeout = timeout;
    }
    
    public ServerConnection(Socket socket, Server server) {
        this.socket = socket;
        this.server = server;
        established = true;
        cmdInterpreter = new CmdInterpretator(this);
     }
    
    public int getSessionId(){
        return sessionId;
    }
    
    public void setSessionId(int val){
        sessionId = val;
    }
    public boolean isLoggedIn(){
        return loggedIn;
    }
    
    public void setLoggedIn(boolean val){
        loggedIn = val;
    }
    
    public void close(){
        established = false;
    }
    
    
     /**
     * Отправляет сообщение клиенту
     *  
     * @param message
     *  сообщение
     * 
     * @return 
     * 
     * Возвращает ответ клиента, или null, если клиент не ответил во время
     */
    public synchronized String send(String message) {
        try {
            out.writeUTF(message);
            out.flush();
        } catch (Exception ex) {
            established = false;
        }
        return null;
    }
    
    private synchronized String receive() throws IOException {
        int time = 0;
        while (in.available() == 0){
            try {
                Thread.sleep(100);
                time += 100;
                if (time >= timeout && loggedIn)
                {
                    established = false;
                    return null;
                }
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
        }
        return in.readUTF();
    }

    public void run() {
        try {
            out = new ObjectOutputStream(socket.getOutputStream()); 
            in = new ObjectInputStream(socket.getInputStream());
        } catch (IOException ex) {
            established = false;
        }
        
        
        while (established) {
            try {
                String cmd = receive();
                cmdInterpreter.performRequest(cmd);
            } catch (IOException ex) {
                established = false;
            }
        }
        
        server.getConnections().remove(this);
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        socket.close();
        in.close();
        out.close();
    }
}
